home *** CD-ROM | disk | FTP | other *** search
/ Disc to the Future 2 / Disc to the Future Part II Programmer's Reference (Wayzata Technology)(6013)(1992).bin / MAC / THINKC / 3_0 / COPYFILE / COPY.C next >
C/C++ Source or Header  |  1989-05-17  |  5KB  |  217 lines

  1. /*
  2.     Copy -- copies one file to another
  3.     
  4.     Instructions for XCMDs are in <XCMD.HowToUse>
  5. */
  6.  
  7. #include <HyperXCmd.h>
  8. #include <SetUpA4.h>
  9.  
  10. /* Constants */
  11. #define NULL        0L
  12. #define FALSE        0
  13. #define TRUE        1
  14. #define BLOCK_SIZE    512
  15.  
  16. /* Macros */
  17. #define strlen(s)            StringLength(paramPtr, (StringPtr) (s))
  18. #define pasToZero(s)        PasToZero(paramPtr, (StringPtr) (s))
  19. #define zeroToPas(s1,s2)    ZeroToPas(paramPtr, (char *) (s1),    \
  20.                             (StringPtr) (s2))
  21. #define numToStr(l,s)        NumToStr(paramPtr, (long) (l), s)
  22.  
  23. /* Static variables */
  24. static char sWrongArgs[] = "\pWrong number of arguments";
  25.  
  26. /* Prototypes */
  27. pascal void main(XCmdBlockPtr);
  28. int CopyFile(char *, char *);
  29. int CopyBytes(IOParam *io1, IOParam *io2, long bytes);
  30.  
  31.  
  32. pascal void main(paramPtr)
  33.     XCmdBlockPtr    paramPtr;
  34. {
  35.     int err;
  36.     Str31 str;
  37.     Str255 source, dest;
  38.  
  39.     RememberA0();
  40.     SetUpA4();
  41.     if (paramPtr->paramCount != 2)
  42.         paramPtr->returnValue = pasToZero(sWrongArgs);
  43.     else {
  44.         zeroToPas(*paramPtr->params[0], source);
  45.         zeroToPas(*paramPtr->params[1], dest);
  46.         err = CopyFile((char *) source, (char *) dest);
  47.         if (err) {
  48.             numToStr(err, &str);
  49.             paramPtr->returnValue = pasToZero(str.guts);
  50.         }
  51.     }
  52.     RestoreA4();
  53. }
  54.  
  55. int CopyFile(source, dest)
  56. char *source, *dest;
  57. {
  58. /*    <FileMgr.h>*/
  59.     FileParam fp1, fp2;
  60.     int err;
  61.     IOParam io1, io2;
  62.  
  63.     /* Start by getting info about the source file */
  64.     fp1.ioCompletion = NULL;
  65.     fp1.ioNamePtr = (StringPtr) source;
  66.     fp1.ioVRefNum = 0;
  67.     fp1.ioFVersNum = 0;
  68.     fp1.ioFDirIndex = 0;
  69.     err = PBGetFInfo(&fp1, FALSE);
  70.     if (err != noErr) {SysBeep(3);
  71.         return (err);}
  72.     
  73.     /* Next create the dest file */
  74.     fp2.ioCompletion = NULL;
  75.     fp2.ioNamePtr = (StringPtr) dest;
  76.     fp2.ioVRefNum = 0;
  77.     fp2.ioFVersNum = 0;
  78.     err = PBCreate(&fp2, FALSE);
  79.     if (err == dupFNErr) {
  80.         /* File already existed -- wipe it out */
  81.         err = PBDelete(&fp2, FALSE);
  82.         if (err != noErr)
  83.             return (err);
  84.         err = PBCreate(&fp2, FALSE);
  85.         if (err != noErr)
  86.             return (err);
  87.     }
  88.     else if (err != noErr)
  89.         return (err);
  90.  
  91.     /* Set the file info on the new file */
  92.     fp2.ioFlFndrInfo = fp1.ioFlFndrInfo;
  93.     fp2.ioFlFndrInfo.fdFlags = 0;
  94.     fp2.ioFlCrDat = fp1.ioFlCrDat;
  95.     fp2.ioFlMdDat = fp1.ioFlMdDat;
  96.     err = PBSetFInfo(&fp2, FALSE);
  97.  
  98.     /* Fill in the I/O params */
  99.     io1.ioCompletion = NULL;
  100.     io1.ioNamePtr = (StringPtr) source;
  101.     io1.ioVRefNum = 0;
  102.     io1.ioVersNum = 0;
  103.     io1.ioPermssn = fsRdPerm;
  104.     io1.ioMisc = NULL;
  105.  
  106.     io2.ioCompletion = NULL;
  107.     io2.ioNamePtr = (StringPtr) dest;
  108.     io2.ioVRefNum = 0;
  109.     io2.ioVersNum = 0;
  110.     io2.ioPermssn = fsWrPerm;
  111.     io2.ioMisc = NULL;
  112.  
  113.     /* Now, copy the files' data forks (if they exist) */
  114.     if (fp1.ioFlLgLen > 0L) {
  115.         /* Start with the destination */
  116.         err = PBOpen(&io2, FALSE);
  117.         if (err != noErr)
  118.             return (err);
  119.         /* Allocate space to copy to */
  120.         io2.ioReqCount = fp1.ioFlLgLen;
  121.         err = PBAllocate(&io2, FALSE);
  122.         if (err != noErr) {
  123.             PBClose(&io2, FALSE);
  124.             return (err);
  125.         }
  126.  
  127.         err = PBOpen(&io1, FALSE);
  128.         if (err != noErr) {
  129.             PBClose(&io2, FALSE);
  130.             return (err);
  131.         }
  132.         err = CopyBytes(&io1, &io2, fp1.ioFlLgLen);
  133.         PBClose(&io1, FALSE);
  134.         PBClose(&io2, FALSE);
  135.         if (err != noErr)
  136.             return (err);
  137.     }
  138.     
  139.     /* Copy the files' resource forks (if they exist) */
  140.     if (fp1.ioFlRLgLen > 0L) {
  141.         /* Start with the destination */
  142.         err = PBOpenRF(&io2, FALSE);
  143.         if (err != noErr)
  144.             return (err);
  145.         /* Allocate space to copy to */
  146.         io2.ioReqCount = fp1.ioFlRLgLen;
  147.         err = PBAllocate(&io2, FALSE);
  148.         if (err != noErr) {
  149.             PBClose(&io2, FALSE);
  150.             return (err);
  151.         }
  152.         err = PBOpenRF(&io1, FALSE);
  153.         if (err != noErr) {
  154.             PBClose(&io2, FALSE);
  155.             return (err);
  156.         }
  157.  
  158.         err = CopyBytes(&io1, &io2, fp1.ioFlRLgLen);
  159.         PBClose(&io1, FALSE);
  160.         PBClose(&io2, FALSE);
  161.         if (err != noErr)
  162.             return (err);
  163.     }
  164.     
  165.     return (err);
  166. }
  167.  
  168. int CopyBytes(io1, io2, bytes)
  169. IOParam *io1, *io2;
  170. long bytes;
  171. {
  172.     char buffer[BLOCK_SIZE];
  173.     long numFullBlocks, i;
  174.     int err;
  175.     
  176.     numFullBlocks = bytes / BLOCK_SIZE;
  177.  
  178.     /* Fill in the missing parts of the I/O params */
  179.     io1->ioBuffer = buffer;
  180.     io1->ioReqCount = BLOCK_SIZE;
  181.     io1->ioPosMode = fsFromStart;
  182.     io1->ioPosOffset = 0L;
  183.     io2->ioBuffer = buffer;
  184.     io2->ioReqCount = BLOCK_SIZE;
  185.     io2->ioPosMode = fsFromStart;
  186.     io2->ioPosOffset = 0L;
  187.  
  188.     /* Note: the following loop copies the number of full blocks.  
  189.        There may be a partial last block. */
  190.     for (i = 0; i < numFullBlocks; i++) {
  191.         err = PBRead(io1, FALSE);
  192.         if (err != noErr)
  193.             return (err);
  194.         err = PBWrite(io2, FALSE);
  195.         if (err != noErr)
  196.             return (err);
  197.     }
  198.     
  199.     /* Copy the last amount */
  200.     io1->ioReqCount = io2->ioReqCount = bytes % BLOCK_SIZE;
  201.     if (io1->ioReqCount != 0L) {
  202.         err = PBRead(io1, FALSE);
  203.         if (err != noErr)
  204.             return (err);
  205.         err = PBWrite(io2, FALSE);
  206.         if (err != noErr)
  207.             return (err);
  208.     }
  209.     
  210.     return (noErr);
  211. }
  212.  
  213. /* C routines for HyperCard callbacks */
  214. #include <XCmdGlue.inc.c>
  215.  
  216.  
  217.